package org.origin.ferret.system.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.origin.centre.model.base.XPage;
import org.origin.centre.model.dto.XDeleteByIdDto;
import org.origin.centre.model.dto.XQueryByIdDto;
import org.origin.centre.model.dto.XUpdateByIdDto;
import org.origin.centre.model.dto.dict.XQueryByTreeValueDto;
import org.origin.centre.model.enums.XDisplay;
import org.origin.centre.model.enums.XUsable;
import org.origin.centre.model.vo.XPageVo;
import org.origin.centre.model.vo.dict.XTreeKeyValueVo;
import org.origin.centre.utils.UserUtil;
import org.origin.ferret.system.mapper.SysMenuMapper;
import org.origin.ferret.system.mapstruct.SysMenuMapstruct;
import org.origin.ferret.system.model.dto.menu.SysMenuInsertDto;
import org.origin.ferret.system.model.dto.menu.SysMenuPageDto;
import org.origin.ferret.system.model.dto.menu.SysMenuUpdateDto;
import org.origin.ferret.system.model.entity.SysMenuEntity;
import org.origin.ferret.system.model.vo.menu.SysMenuVo;
import org.origin.ferret.system.service.SysMenuService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

import static org.origin.ferret.system.model.entity.table.SysMenuEntityTableDef.SYS_MENU_ENTITY;

/**
 * 系统菜单-服务
 *
 * @author ferret
 * @version 2024-05-08
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysMenuServiceImpl implements SysMenuService {
    private final SysMenuMapper menuMapper;
    private final SysMenuMapstruct menuMapstruct;

    @Override
    public XPageVo<SysMenuVo> page(XPage<SysMenuPageDto> pageDto) {
        SysMenuPageDto params = pageDto.getParams();
        Page<SysMenuEntity> pagePojo = this.menuMapper
                .paginate(pageDto.getPageNum(), pageDto.getPageSize(), QueryWrapper.create()
                        .where(SYS_MENU_ENTITY.PARENT_ID.eq(params.getParentId(), !UserUtil.isAdmin()))
                        .and(SYS_MENU_ENTITY.NAME.like(params.getName(), StringUtils::isNotBlank))
                        .and(SYS_MENU_ENTITY.TYPE.eq(params.getType(), Objects::nonNull))
                        .and(SYS_MENU_ENTITY.STATUS.eq(params.getStatus(), Objects::nonNull))
                        .orderBy(SYS_MENU_ENTITY.STATUS.asc())
                        .orderBy(SYS_MENU_ENTITY.CREATE_TIME.desc())
                        .orderBy(SYS_MENU_ENTITY.ID.desc())
                );
        return new XPageVo<SysMenuVo>()
                .of(pageDto, pagePojo.getTotalRow(),
                        pagePojo.getRecords(), this.menuMapstruct::toVo);
    }

    @Override
    public SysMenuVo query(XQueryByIdDto queryDto) {
        SysMenuEntity entity = this.menuMapper.selectOneById(queryDto.getId());
        return this.menuMapstruct.toVo(entity);
    }

    @Override
    public Boolean insert(SysMenuInsertDto insertDto) {
        SysMenuEntity entity = this.menuMapstruct.toEntity(insertDto);
        if (entity.getDisplay() != null) {
            if (!XDisplay.YES.isEqual(entity.getDisplay()) &&
                    !XDisplay.NO.isEqual(entity.getDisplay())) {
                entity.setDisplay(XDisplay.YES.getCode());
            }
        }
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preInsert();
        int insertNum = this.menuMapper.insert(entity);
        return insertNum > 0;
    }

    @Override
    public Boolean update(SysMenuUpdateDto updateDto) {
        SysMenuEntity entity = this.menuMapstruct.toEntity(updateDto);
        entity.setStatus(null);
        if (entity.getDisplay() != null) {
            if (!XDisplay.YES.isEqual(entity.getDisplay()) &&
                    !XDisplay.NO.isEqual(entity.getDisplay())) {
                entity.setDisplay(null);
            }
        }
        entity.preUpdate();
        int updateNum = this.menuMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean delete(XDeleteByIdDto deleteDto) {
        int updateNum = this.menuMapper.deleteById(deleteDto.longId());
        return updateNum > 0;
    }

    @Override
    public Boolean valid(XUpdateByIdDto updateDto) {
        SysMenuEntity entity = new SysMenuEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.USABLE.getCode());
        entity.preUpdate();
        int updateNum = this.menuMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public Boolean invalid(XUpdateByIdDto updateDto) {
        SysMenuEntity entity = new SysMenuEntity();
        entity.setId(updateDto.longId());
        entity.setStatus(XUsable.DISABLE.getCode());
        entity.preUpdate();
        int updateNum = this.menuMapper.update(entity);
        return updateNum > 0;
    }

    @Override
    public List<XTreeKeyValueVo> list(XQueryByTreeValueDto queryDto) {
        return null;
    }
}
